/**
 * @author:莫若省
 * axios 配置项文件
 * axios调用时请使用async await处理异步请求
 */
import axios, {
  InternalAxiosRequestConfig,
  AxiosResponse,
  AxiosError,
} from 'axios';
import { AXIOS_CONFIG } from './axiosConfig';
import { statusErrorCodeType } from './statusErrorCodeType';
import { promiseErrorCodeType } from './promiseErrorCodeType';
import { useStorage } from '@/hook/useStorage';
import { createSystemLog } from '@/log/systemLog';
import { AxiosResponseDataInterface } from '@/networkService/axiosInterface';

// 创建 axios 实例
const networkService = axios.create({
  baseURL: AXIOS_CONFIG.BASE_URL,
  timeout: AXIOS_CONFIG.TIME_OUT,
});

// 请求拦截器
networkService.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 获取token
    const Authorization = useStorage.getItem(AXIOS_CONFIG.TOKEN);
    if (Authorization) {
      // 配置token
      config.headers[AXIOS_CONFIG.TOKEN] = Authorization;
    }
    // 取消重复请求
    const controller = new AbortController();
    const key = config.data + config.url;
    config.signal = controller.signal;
    if (AXIOS_CONFIG.REQUEST_MAP.has(key)) {
      AXIOS_CONFIG.REQUEST_MAP.get(key).abort();
      AXIOS_CONFIG.REQUEST_MAP.delete(key);
    } else {
      AXIOS_CONFIG.REQUEST_MAP.set(key, controller);
    }
    return config;
  },
  (error: AxiosError) => {
    return Promise.reject(error);
  },
);
// 响应拦截器
networkService.interceptors.response.use(
  (response: AxiosResponse) => {
    const { code } = response.data as AxiosResponseDataInterface;
    // 当结果按照约定返回时的处理逻辑
    if (+code !== 200) promiseErrorCodeType(response.data);
    // 将成功结果生成日志
    createSystemLog('axiosLog', response);
    return response.data;
  },
  (errorResponse: AxiosError) => {
    // 将结果生成日志
    createSystemLog('axiosLog', errorResponse);
    // 对服务器状态码错误统一处理
    statusErrorCodeType(errorResponse.request.status);
  },
);

// 对外暴露二次封装好的axios请求
export default networkService;
